<script>
import PropertyString from './components/string'
import PropertyBoolean from './components/boolean'
import PropertyColor from './components/color'
import PropertyList from './components/list'
import PropertyInteger from './components/int'
import PropertyFloat from './components/float'
// import PropertyFloatV2 from './components/float-v2'
import PropertyXYZ from './components/xyz'
import PropertyLineWeight from './components/line-weight.vue'
import Field from './field'
import { makeUUID } from '@/utils'
import { isValidType } from '@/utils/types'

// 使用d2-crud组件实现的属性网格控件
export default {
  name: 'PropertyData',
  components: {
    PropertyString,
    PropertyBoolean,
    PropertyColor,
    PropertyList,
    PropertyInteger,
    PropertyFloat,
    // PropertyFloatV2,
    PropertyXYZ,
    PropertyLineWeight
  },
  props: {
    value: {
      type: String,
      required: true
    },
    // 父组件传入的函数
    isInEdit: {
      type: Function,
      required: true
    },
    completeEdit: {
      type: Function,
      required: true
    },
    getObject: {
      type: Function,
      required: true
    },
    // 本行的所有数据，此字段不需要额外配置
    // console.log('scope:', this.scope)
    // console.log('value:', this.value)
    // rowIndex 为改变所在行，key 为改变的字段，value 为改变后的值，row 是改变所在行的所有数据
    // row=this.scope.row (row.field, row.value)
    // column=this.scope.column (column.property)
    // const rowIndex = ths.scope.$index
    // const key = that.scope.column.property
    // const row = that.scope.row
    scope: {
      type: Object,
      default: null
    }
  },
  data() {
    return {
      proxyValue: '' // 代理value
    }
  },
  computed: {
    // 是否处于编辑状态
    inEdit: function() {
      // 使用父组件传进来的函数来判断是否正在编辑!!!
      return this.isInEdit(this.scope)
    }
  },
  // watch: {
  //   // 转变为非编辑状态的时候,向父组件发送change消息
  //   inEdit (val) {
  //     // 1、由编辑状态变为非编辑状态
  //     // 2、数据被修改
  //     if (!val && this.proxyValue !== this.value) {
  //       // 向父组件发送input消息(满足v-model语法糖需要!!!)
  //       // console.log('触发inEdit变化。。。。')
  //       this.$emit('input', this.proxyValue)
  //       // console.log('value=', this.value)
  //       // console.log('proxy=', this.proxyValue)
  //     }
  //   }
  // },
  created() {
    this.init()
  },
  methods: {
    init() {
      this.proxyValue = this.value
    },
    // change事件处理函数
    // 接收子组件发送的change消息,并修改proxyValue
    onChange(value) {
      this.proxyValue = value
      if (this.proxyValue !== this.value) {
        this.$emit('input', this.proxyValue)
      }
      // 取消编辑状态(通过函数修改父组件的参数)
      this.completeEdit()
    }
  },
  render: function(h) {
    // 通过scope.row得到行数据
    const obj = this.getObject(this.scope.row.field)
    let type = Field.STRING
    let args = {}
    let useList = false
    if (obj !== null) {
      if (isValidType(obj.type, 'Number')) {
        type = obj.type
      }
      if (isValidType(obj.args, 'Object')) {
        args = obj.args
      }
      if (isValidType(args.useList, 'Boolean')) {
        useList = args.useList
        // 删除args中useList参数
        delete args.useList
      }
      // useList=true,必须提供options数组!!!
      if (useList) {
        const hack = t => {
          if (!isValidType(args.options, 'Array')) {
            // 删除options(如果有的话)
            delete args.options
            // 改用其他组件类型
            type = t
            // 不使用列表
            useList = false
          }
        }
        // 两种情况：
        // 1、线宽取值只能是整数
        // 2、args不包含有效的options参数
        if (type === Field.INT) {
          hack(Field.INT)
        } else if (type === Field.FLOAT) {
          hack(Field.FLOAT)
        } else if (type === Field.STRING) {
          hack(Field.STRING)
        } else if (type === Field.LINEWEIGHT) {
          hack(Field.INT)
        } else if (type === Field.LINETYPE) {
          hack(Field.STRING)
        } else {
          delete args.options
          useList = false
        }
      }
      // args中仍然保留useList参数(后续待用)
      args.useList = useList
    }
    // 是否只读
    let readOnly = false
    if (isValidType(obj.readOnly, 'Boolean')) {
      readOnly = obj.readOnly
    }
    const props = {
      value: this.value, // value是一个字符串
      scope: this.scope,
      inEdit: this.inEdit && !readOnly,
      ...args // es6解构语法,附加其它的参数
    }
    const on = {
      change: this.onChange
    }
    let tag = 'PropertyString'
    if (type === Field.STRING) {
      tag = useList ? 'PropertyList' : 'PropertyString'
    } else if (type === Field.INT) {
      tag = useList ? 'PropertyList' : 'PropertyInteger'
    } else if (type === Field.FLOAT) {
      // 简单的浮点数组件
      tag = useList ? 'PropertyList' : 'PropertyFloat'
      // 带精度选择功能的浮点数组件
      // tag = useList ? 'PropertyList' : 'PropertyFloatV2'
    } else if (type === Field.BOOLEAN) {
      // 布尔组件
      tag = 'PropertyBoolean'
    } else if (type === Field.POINT || type === Field.VECTOR) {
      // xyz点坐标组件
      tag = 'PropertyXYZ'
    } else if (type === Field.COLOR) {
      // 颜色组件
      tag = 'PropertyColor'
    } else if (type === Field.LINETYPE) {
      tag = useList ? 'PropertyList' : 'PropertyString'
    } else if (type === Field.LINEWEIGHT) {
      tag = useList ? 'PropertyLineWeight' : 'PropertyInteger'
    }

    const key = makeUUID() // 避免同类型组件发生冲突!!!
    // console.log(
    //   obj.key,
    //   'property-data render函数: props =',
    //   props,
    //   ' tag =',
    //   tag,
    //   'value =',
    //   this.value,
    //   'key =',
    //   key
    // )
    return h(tag, {
      props,
      on,
      key
    })
  }
}
</script>
